package org.now.ypos.user.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.now.ypos.controller.BaseController;
import org.now.ypos.dto.ApiResponse;
import org.now.ypos.user.dto.UserDto;
import org.now.ypos.user.dto.UserStruct;
import org.now.ypos.user.entity.User;
import org.now.ypos.user.service.UserService;
import org.now.ypos.util.YposConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * UserController.
 *
 * @author wl
 * @since 2020.11.10
 */
@RestController
@RequestMapping(YposConst.API_PREFIX_USER)
public class UserController extends BaseController {

    /**
     * LOGGER.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    /**
     * UserService for process logic.
     */
    private final UserService userService;


    /**
     * Constructor for UserController.
     *
     * @param userService userService
     */
    public UserController(final UserService userService) {
        this.userService = userService;
    }

    /**
     * Get By Id.
     *
     * @param id id
     * @return ApiResponse with UserDto
     */
    @GetMapping("/{id}")
    public final ResponseEntity<ApiResponse> getById(@PathVariable final Long id) {
        final var user = userService.getById(id);
        if (Objects.isNull(user)) {
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(ApiResponse.success(UserStruct.INSTANCE.toDto(user)));
    }

    /**
     * Create User.
     *
     * @param userDto userDto
     * @return ApiResponse with UserDto
     */
    @PostMapping()
    public final ResponseEntity<ApiResponse> post(@RequestBody final UserDto userDto) {
        setCommonFieldForCreate(userDto);
        final var user = userService.save(userDto);
        return ResponseEntity.ok(ApiResponse.success(UserStruct.INSTANCE.toDto(user)));
    }

    /**
     * Update User.
     *
     * @param userDto userDto
     * @return ApiResponse with UserDto
     */
    @PutMapping()
    public final ResponseEntity<ApiResponse> put(@RequestBody final UserDto userDto) {
        Objects.requireNonNull(userDto.getId(), "User Id should not be null when update.");
        setCommonFieldForUpdate(userDto);
        final var user = userService.update(userDto);
        return ResponseEntity.ok(ApiResponse.success(UserStruct.INSTANCE.toDto(user)));
    }

    /**
     * Delete by id.
     *
     * @param id id
     * @return ApiResponse with effected rows
     */
    @DeleteMapping("/{id}")
    public final ResponseEntity<ApiResponse> delete(@PathVariable final Long id) {
        final var rows = userService.deleteById(id);
        LOGGER.debug("delete user rows {}, id {}", rows, id);
        return ResponseEntity.ok(ApiResponse.success(rows));
    }

    /**
     * Find user by page and UserDto.
     *
     * @param userDto userDto
     * @param current current
     * @param size    size
     * @return ApiResponse with page data
     */
    @PostMapping("find")
    public final ResponseEntity<ApiResponse> find(@RequestBody final UserDto userDto,
                                                  @RequestParam final int current,
                                                  @RequestParam final int size) {
        final var page = new Page<User>(current, size);
        final var userPage = userService.findPage(userDto, page);
        final var userDtoList = UserStruct.INSTANCE.toDtoList(userPage.getRecords());
        final var userDtoPage = new Page<UserDto>();
        BeanUtils.copyProperties(userPage, userDtoPage);
        userDtoPage.setRecords(userDtoList);
        return ResponseEntity.ok(ApiResponse.success(userDtoPage));
    }

}
